import styled from "./index.module.scss"
import {useCallback, useEffect, useMemo} from 'react'
import {shoppingDel, shoppingList, shoppingOrder} from '@/api'
import useStateReducer from '@/hooks/useStateReducer'
import {ShoppingList} from '@/type/shopping'
import {Checkbox, Input, message} from 'antd'
import config from '@/static/config'
import {useNavigate} from 'react-router-dom'
import Base64 from '@/utils/base64'
import {MinusOutlined, PlusOutlined} from '@ant-design/icons'

type ShoppingTable = ShoppingList & { check: boolean}

type ActionTypeString = "LIST" | "MONEY" | "CHECK"

type initState = {
  list: ShoppingTable[]
  productNum: number,
  check: boolean
}

type ActionType = {
  type: ActionTypeString,
  payload: Partial<initState>
}

const state:initState = {
  list: [],
  productNum: 0,
  check: false
}

const reducer = (store:initState, action:ActionType) => {
  const {type, payload} = action
  switch (type) {
    case 'LIST':
      return {
        ...store,
        list: payload.list
      }
    case 'MONEY':
      return {
        ...store,
        productNum: payload.productNum!
      }
    case 'CHECK':
      return {
        ...store,
        check: payload.check!,
        list: payload.list!
      }
  }
  return store
}

const Shopping = () => {
  const navigate = useNavigate()
  const [store, dispatch] = useStateReducer(reducer, state)

  const getList = useCallback(() => {
    shoppingList().then(res => {
      if (res.code === 200) {
        dispatch({
          type: 'LIST',
          payload: {
            list: res.data.map(item => ({
              ...item,
              check: false
            }))
          }
        })
      }
    })
  }, [])

  useEffect(() => {
    getList()
  }, [])
  useEffect(() => {
    if (store.check) {
      const list = store.list!.filter(item => !item.check).length
      // 全选时判断下面列表中如果没有选中的则全部选中
      if (list) {
        dispatch({
          type: "LIST",
          payload: {
            list: store.list!.map(item => ({
              ...item,
              check: true
            }))
          }
        })
      }
    }
  }, [store])
  // 全选
  const tableHeadCheckChange = useCallback(() => {
    dispatch({
      type: "CHECK",
      payload: {
        check: !store.check!,
        list: store.list?.map(item => ({
          ...item,
          check: !store.check!
        }))
      }
    })
  }, [store])
  // 单独商品选中
  const tableBodyCheckChange = useCallback((table: ShoppingTable, i: number) => {
    const rows:ShoppingTable = JSON.parse(JSON.stringify(table))
    rows.check = !table.check
    const list = store.list!
    list[i] = rows
    const flag = !list.filter( key => !key.check ).length
    dispatch({
      type: "CHECK",
      payload: {
        list,
        check: flag
      }
    })
  }, [store])
  // 跳转商品详情页面
  const priductInfoClick = useCallback((item: ShoppingTable) => {
    const base:Base64 = new Base64()
    const str = `product_id=${item.product_id}`
    navigate(`/home/productinfo/${base.encode(str)}`,{
      replace: true
    })
  }, [store])
  // 移出购物车
  const shoppingDelete = useCallback((item:ShoppingTable) => {
    shoppingDel({
      id: item.id!
    }).then(res => {
      if (res.code === 200) {
        message.success(res.message)
        getList()
      }
    })
    // console.log(item)
  }, [store])
  // 数量添加
  const shoppingItemAdd = useCallback((item: ShoppingTable, i: number) => {
    const rows:ShoppingTable = JSON.parse(JSON.stringify(item))
    rows.cart_num = item.cart_num + 1
    const list = store.list!
    list[i] = rows
    dispatch({
      type: 'LIST',
      payload: {
        list
      }
    })
  }, [store])
  // 数量相减
  const shoppingItemMinus = useCallback((item: ShoppingTable, i: number) => {
    if (item.cart_num !== 1) {
      const rows:ShoppingTable = JSON.parse(JSON.stringify(item))
      rows.cart_num = item.cart_num - 1
      const list = store.list!
      list[i] = rows
      dispatch({
        type: 'LIST',
        payload: {
          list
        }
      })
    }
  }, [store])
  // 修改数量
  const shoppingItemChange = useCallback((item:ShoppingTable, i: number, e:{
    currentTarget: HTMLInputElement
    target: HTMLInputElement
  }) => {
    const rows:ShoppingTable = JSON.parse(JSON.stringify(item))
    const value = e.target.value
    const regexp:RegExp = /[^\d]/g
    console.log(regexp.test(value))
    if (regexp.test(value)) {
      rows.cart_num = 1
    }else {
      if (value <= 0) {
        rows.cart_num = 1
      }else {
        rows.cart_num = Number(value)
      }
    }
    if (isNaN(rows.cart_num)) {
      rows.cart_num = 1
    }
    const list = store.list!
    list[i] = rows
    dispatch({
      type: 'LIST',
      payload: {
        list
      }
    })
  }, [store])
  // 结算点击事件
  const shoppingSettleClick = useCallback(() => {
    const list = store.list!
    // console.log(list)
    shoppingOrder(list.map(item => {
      delete item.check
      return item
    })).then(res => {
      if (res.code === 200) {
        navigate("/home/settle",{
          replace: true
        })
      }
    })
  }, [store])
  // 按钮
  const button = useMemo(() => {
    const list = store.list!.filter(item => item.check)
    if (list.length) {
      return <button onClick={shoppingSettleClick} className={styled.shopping_header_right_btn}>结算</button>
    }
    return <button>结算</button>
  }, [store])
  // 表格
  const table = useMemo(() => {
    return store.list?.map((item, i) => (
      <div
        key={item.id}
        className={item.check ? styled.shopping_table_tbody_rowActive : styled.shopping_table_tbody_row}
      >
        <div>
          <Checkbox checked={item.check} onChange={() => tableBodyCheckChange(item, i)}></Checkbox>
        </div>
        <div>
          <img onClick={() => priductInfoClick(item)} height={80} width={100} src={config.productImgUrl + item.product_pic} alt=""/>
          <span onClick={() => priductInfoClick(item)}>{item.product_name}</span>
        </div>
        <div>{item.cart_money.toFixed(2)}</div>
        <div>{
          item.discount ? item.discount.toFixed(2) : ""
        }</div>
        <div>

          <Input
            addonBefore={
              <MinusOutlined onClick={() => shoppingItemMinus(item, i)} className={item.cart_num === 1 ? styled.no_icon : styled.icon} />
            }
            value={item.cart_num}
            onChange={(e) => shoppingItemChange(item, i, e)}
            addonAfter={
              <PlusOutlined onClick={() => shoppingItemAdd(item, i)} className={styled.icon}/>
            }
          ></Input>
        </div>
        <div>{ item.discount ? (item.discount * item.cart_num).toFixed(2) : (item.cart_money * item.cart_num).toFixed(2) }</div>
        <div>
          <span onClick={() => shoppingDelete(item)}>移除购物车</span>
        </div>
      </div>
    ))
  }, [store])
  // 总价格
  const moneyTotal = useMemo(() => {
    let num = 0
    const list = store.list!
    list.forEach(item => {
      if (item.check) {
        if (item.discount) {
          num += item.cart_num * item.discount
        } else {
          num += item.cart_num * item.cart_money
        }

      }
    })
    return num.toFixed(2)
  }, [store])

  return (
    <div className={styled.shopping}>
      <div className={styled.shopping_header}>
        <h3>购物车 &#40;<span>全部{store.list.length}</span>&#41;</h3>
        <div className={styled.shopping_header_right}>
          <span>已选商品</span>
          <span className={styled.shopping_header_money}>{moneyTotal}</span>
          {button}
        </div>
      </div>
      <div className={styled.shopping_table}>
        <div className={styled.shopping_table_thead}>
          <div><Checkbox checked={store.check} onChange={tableHeadCheckChange}/>全选</div>
          <div>商品信息</div>
          <div>单价</div>
          <div>折扣价格</div>
          <div>数量</div>
          <div>金额</div>
          <div>操作</div>
        </div>
        <div className={styled.shopping_table_tbody}>
          {table}
        </div>
      </div>
    </div>
  )
}


export default Shopping
